﻿using AntUnion.FrameWork.Model.Models;
using AntUnion.FrameWork.Util;
using AntUnion.FrameWork.Web.Common;
using MetaQuotes.MT5WebAPI;
using MetaQuotes.MT5WebAPI.Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RM.Common.DotNetEamil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AntUnion.FrameWork.Web.Service
{
    public class MT5CommonHelper
    {
        private static MT5WebAPI m_WebApi;
        private ulong login;

        #region 登录MT5WebApi服务器
        public bool Connect(mtContext _context)
        {
            DateTime? ResTime = DateTimeUtil.Now;
            Result res = new Result();
            m_WebApi = new MT5WebAPI();
            Mt5Server mt5 = _context.Mt5Servers.Find(1);
            UInt64.TryParse(mt5.MetatraderLogin, out login);
            Int32 port = 0;
            Int32.TryParse(mt5.MetatraderPort, out port);
            MTRetCode code = m_WebApi.Connect(mt5.MetatraderServer, port, login, mt5.MetatraderPassword, MT5WebAPI.EnPumpModes.PUMP_MODE_NONE, MT5WebAPI.EnCryptModes.CRYPT_MODE_AES, 1000);
            if (code == MTRetCode.MT_RET_OK)
            {
                MTConGroup mTConGroup = new MTConGroup();
                code = m_WebApi.GroupNext(0, out mTConGroup);
                res.Data = code.ToString();
                res.Code = 0;
                AddMt5Log(_context, "Connect", ResTime, JsonConvert.SerializeObject(res), 0);
                return true;
            }
            else
            {
                res.Msg = code.ToString();
                res.Code = 1;
                AddMt5Log(_context, "Connect", ResTime, JsonConvert.SerializeObject(res), 1);
                return false;
            }

        }

        public bool TestConnect(mtContext _context, string metatrader_server, string metatrader_password, string metatrader_login, string metatrader_port)
        {
            DateTime? ResTime = DateTimeUtil.Now;
            Result res = new Result();
            MT5WebAPI m_WebApi1 = new MT5WebAPI();

            UInt64.TryParse(metatrader_login, out login);
            Int32 port = 0;
            Int32.TryParse(metatrader_port, out port);
            MTRetCode code = m_WebApi1.Connect(metatrader_server, port, login, metatrader_password, MT5WebAPI.EnPumpModes.PUMP_MODE_NONE, MT5WebAPI.EnCryptModes.CRYPT_MODE_AES, 1000);
            if (code == MTRetCode.MT_RET_OK)
            {
                return true;
            }
            else
            {

                return false;
            }
        }
        #endregion

        public static object[] GetMethodParameterValues(object res, params object[] objs)
        {
            string outPut = JsonConvert.SerializeObject(res);
            string inPut = "";
            foreach (object obj in objs)
            {
                inPut += obj + "|";
            }
            return null;
        }

        #region 判断Web客户连接MT5的状态
        public void Mt5State()
        {
            using (mtContext _context = new mtContext())
            {
                bool t = m_WebApi.IsConnected;
                if (t == false)
                {
                    Connect(_context);
                    t = m_WebApi.IsConnected;
                    if (t == false)
                    {
                        throw new Exception("MT5连接失败");
                    }
                }
            }

        }
        #endregion

        #region 接口操作日志
        public void AddMt5Log(mtContext _context, string cont, DateTime? ResTime, string Res, int result)
        {
            Mt5ApiLog mt5ApiLog = new Mt5ApiLog();
            mt5ApiLog.Url = cont;
            mt5ApiLog.Req = "";
            mt5ApiLog.ReqTime = ResTime;
            mt5ApiLog.Res = Res;
            mt5ApiLog.ResTime = DateTimeUtil.Now;
            mt5ApiLog.Result = result;
            _context.Add(mt5ApiLog);
            //_context.SaveChanges();

        }
        #endregion

        #region MT5账户注册
        public bool Registered(mtContext _context, MTUser tmu, out MTUser mu)
        {
            Mt5State();
            DateTime? ResTime = DateTimeUtil.Now;
            Result res = new Result();
            MTRetCode code = m_WebApi.UserAdd(tmu, out mu);

            if (code == MTRetCode.MT_RET_OK)
            {
                res.Code = 0;
                res.Data = tmu;


                AddMt5Log(_context, "UserAdd", ResTime, JsonConvert.SerializeObject(res).ToString(), 0);
                return true;
            }
            else
            {
                res.Code = 1;
                res.Msg = code.ToString();
                AddMt5Log(_context, "UserAdd", ResTime, JsonConvert.SerializeObject(res).ToString(), 1);
                return false;
            }
        }


        #endregion

        #region 验证MT5账户登录密码
        public bool CheckingLogin(mtContext _context, string Mt5login, string Mt5password)
        {
            Mt5State();
            DateTime? ResTime = DateTimeUtil.Now;
            Result res = new Result();
            ulong.TryParse(Mt5login, out login);
            MTRetCode code = m_WebApi.UserPasswordCheck(login, Mt5password);
            if (code == MTRetCode.MT_RET_OK)
            {
                res.Data = code.ToString();
                res.Code = 0;
                AddMt5Log(_context, "UserPasswordCheck", ResTime, JsonConvert.SerializeObject(res), 0);
                return true;
            }
            else
            {
                res.Msg = code.ToString();
                res.Code = 1;
                AddMt5Log(_context, "UserPasswordCheck", ResTime, JsonConvert.SerializeObject(res), 1);
                return false;
            }
        }
        #endregion

        #region 查询Mt5用户信息
        public MTUser QueryUsers(ulong login)
        {
            Mt5State();
            DateTime? ResTime = DateTimeUtil.Now;
            MTUser tmu = new MTUser();
            MTRetCode code = m_WebApi.UserGet(login, out tmu);
            return tmu;

        }
        #endregion

        #region 查询Mt5账户的信息
        public MTAccount QueryUserAccount(ulong login)
        {
            Mt5State();
            MTAccount mta = new MTAccount();
            MTRetCode code = m_WebApi.UserAccountGet(login, out mta);
            return mta;

        }
        #endregion

        #region 修改账户密码
        /// <summary>
        /// 更改客户的密码。
        /// </summary>
        /// <param name="login"></param>
        /// <param name="newPassword">密码</param>
        /// <param name="EnUsersPasswords">密码类型</param>
        /// <returns></returns>
        public bool UpdatePassword(ulong login, string newPassword, MTUser.EnUsersPasswords EnUsersPasswords)
        {
            Mt5State();
            MTRetCode code = m_WebApi.UserPasswordChange(login, newPassword, EnUsersPasswords);
            if (code == MTRetCode.MT_RET_OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 修改个人信息
        /// <summary>
        /// 更改服务器上的客户账户
        /// </summary>
        /// <param name="mt1"></param>
        /// <param name="mt2"></param>
        /// <returns></returns>
        public bool UpdateUser(MTUser mt1, out MTUser mt2)
        {

            Mt5State();
            MTRetCode code = m_WebApi.UserUpdate(mt1, out mt2);
            if (code == MTRetCode.MT_RET_OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 删除服务器上的客户账户
        public bool UserDelete(ulong login)
        {
            Mt5State();
            MTRetCode code = m_WebApi.UserDelete(login);
            if (code == MTRetCode.MT_RET_OK)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 对账户进行结余操作
        /// <summary>
        /// 对账户进行结余操作
        /// </summary>
        /// <param name="login"></param>
        /// <param name="EnDealAction">操作类型 DEAL_BALANCE:结余操作,DEAL_CREDIT:信贷操作,DEAL_CHARGE:额外添加/提取,DEAL_CORRECTION:更正操作,DEAL_BONUS:添加奖金</param>
        /// <param name="money">金额</param>
        /// <param name="context">备注</param>
        /// <param name="toamount">实际到账金额</param>
        /// <param name="fees">手续费</param>
        /// <param name="ticker">结余交易的单号</param>
        /// <returns></returns>
        public bool TradeBalance(mtContext _context, ulong login, MTDeal.EnDealAction EnDealAction, string operationMode, double money, string context, double toamount, decimal fees, string creator, out ulong ticker)
        {
            Mt5State();
            MTRetCode code = m_WebApi.TradeBalance(login, EnDealAction, toamount, context, out ticker);
            if (code == MTRetCode.MT_RET_OK)
            {
                Mt5Transaction mt5Transaction = new Mt5Transaction();
                mt5Transaction.Id = CommonHelper.GetOrderNo();
                mt5Transaction.Login = Convert.ToInt64(login);
                mt5Transaction.Amount = Convert.ToDecimal(money);
                mt5Transaction.Type = operationMode;
                mt5Transaction.CreateDate = DateTimeUtil.Now;
                mt5Transaction.OrderId = ticker.ToString();
                mt5Transaction.Remark = context;
                mt5Transaction.Toamount = Convert.ToDecimal(toamount);
                mt5Transaction.Creator = creator;
                mt5Transaction.Fees = fees;
                _context.Mt5Transactions.Add(mt5Transaction);
                _context.SaveChanges();

                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 通过登录获得客户的开仓订单(这个好像和下面一个一样)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="login"></param>
        /// <param name="Offset">订单的指数，您需要获得的订单从其开始。编号从 0 开始。</param>
        /// <param name="Total">应该获得的订单的数目。可以在一个方法调用中请求的订单的最大数目是 100。</param>
        /// <returns></returns>
        public List<MTOrder> GetOrdersGetPageList(ulong login, uint Offset, uint Total)
        {
            Mt5State();
            List<MTOrder> orders = new List<MTOrder>();
            MTRetCode code = m_WebApi.OrderGetPage(login, Offset, Total, out orders);
            return orders;
        }
        #endregion

        #region 通过登录获得客户的开仓(这个好像和上面一个一样)
        /// <summary>
        /// 通过登录获得客户的开仓
        /// </summary>
        /// <param name="login"></param>
        /// <param name="Offset">持仓的指数，您需要获得的持仓从其开始。编号从 0 开始。</param>
        /// <param name="Total">应该获得的持仓的数目。可以在一个方法调用中请求的持仓的最大数目是 100</param>
        /// <returns></returns>
        public List<MTPosition> PositionGetPage(ulong login, uint Offset, uint Total)
        {
            Mt5State();
            List<MTPosition> positions = new List<MTPosition>();
            MTRetCode code = m_WebApi.PositionGetPage(login, Offset, Total, out positions);
            return positions;
        }
        #endregion

        #region 通过登录获得客户的平仓订单。
        /// <summary>
        /// 通过登录获得客户的平仓订单。
        /// </summary>
        /// <param name="login"></param>
        /// <param name="startTime">请求订单的时期的开始。该日期以自 1970 年 1 月 1 日以来的秒数指定。</param>
        /// <param name="endTime"> 请求订单的时期的结束。该日期以自 1970 年 1 月 1 日以来的秒数指定。</param>
        /// <param name="Offset">订单的指数，您需要获得的订单从其开始。编号从 0 开始。</param>
        /// <param name="Total">应该获得的订单的数目。可以在一个方法调用中请求的订单的最大数目是 100。</param>
        /// <returns></returns>
        public List<MTOrder> HistoryGetPage(ulong login, long startTime, long endTime, uint Offset, uint Total)
        {
            Mt5State();
            List<MTOrder> orders = new List<MTOrder>();
            MTRetCode code = m_WebApi.HistoryGetPage(login, startTime, endTime, Offset, Total, out orders);
            return orders;
        }
        #endregion

        #region 获取组别

        #endregion

    }
}
